from __future__ import annotations

import io

from model import Settings, Request, Action, ReloadAction, VisitAction, OffloadAction

from pytablewriter import (
    AbstractTableWriter,
    TableWriterFactory,
)


class Comparator:
    """
    Compare different action sequences for the same set of requests.
    """

    def __init__(
        self,
        settings: Settings,
        requests: list[Request],
        actions: dict[str, list[Action]],
        style: str,
    ):
        self.settings = settings
        self.requests = requests
        self.actions = actions
        self.style = style
        self.table_writer: AbstractTableWriter = (
            TableWriterFactory.create_from_format_name(style)
        )

    def emit_table(self) -> str:
        """
        Emit a comparison table of the different action sequences for each request.

        Table columns:
        - Algorithm name
        - Finish time
        - Computation time
        - IO time
        - IO count
        - Computation-IO overlapping time ratio
        """
        # Prepare table data
        value_matrix = []
        for algo_name, action_list in self.actions.items():
            finish_time = action_list[-1].time
            computation_time = sum(
                action.cost()
                for action in action_list
                if isinstance(action, VisitAction)
            )
            io_time = sum(
                action.cost()
                for action in action_list
                if isinstance(action, (ReloadAction, OffloadAction))
            )
            io_count = sum(
                1
                for action in action_list
                if isinstance(action, (ReloadAction, OffloadAction))
            )
            comp_io_overlap_time_ratio = (
                computation_time + io_time - finish_time
            ) / io_time
            value_matrix.append(
                [
                    algo_name,
                    finish_time,
                    computation_time,
                    io_time,
                    io_count,
                    f"{comp_io_overlap_time_ratio:.2f}",
                ]
            )

        # Fill table headers and value matrix
        self.table_writer.headers = [
            "Algorithm",
            "Finish Time",
            "Computation Time",
            "IO Time",
            "IO Count",
            "Comp-IO Overlap Time Ratio",
        ]
        self.table_writer.value_matrix = value_matrix

        # Use string stream to capture output
        output_stream = io.StringIO()
        self.table_writer.stream = output_stream
        self.table_writer.write_table()

        return output_stream.getvalue()

    @classmethod
    def list_styles(cls) -> list[str]:
        """
        List available output styles for the comparison table.
        """
        return TableWriterFactory.get_format_names()
